package com.misty.auth.filter;

import com.alibaba.fastjson.JSON;
import com.misty.auth.component.LoginUser;
import com.misty.auth.service.impl.UserServiceImpl;
import com.misty.common.Util.JwtUtil;
import com.misty.common.Util.RedisCache;
import com.misty.common.Util.WebUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
@Slf4j
public class LoginFilter extends OncePerRequestFilter {

    @Autowired
    RedisCache redisCache;

    @Autowired
    private UserServiceImpl userService;


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        String token = null;
        String redisKey = null;
        Claims claims = null;
        String userid = null;


        token  = request.getHeader("token");
        log.info("======token authenticated======");
        if(token == null){
            filterChain.doFilter(request,response);
            return;
        }

        try {
            claims = JwtUtil.parseJWT(token);
            userid = claims.getSubject();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("token非法");
        }


        redisKey = "login_" + userid;
//        LoginUser loginUser = (LoginUser) redisCache.getCacheObject(redisKey);
        LoginUser loginUser;
        Object cacheObject = redisCache.getCacheObject(redisKey);
        if (cacheObject instanceof LoginUser) {
            loginUser = (LoginUser) cacheObject;
        } else {
            loginUser = JSON.parseObject(JSON.toJSON(cacheObject).toString(), LoginUser.class);
        }

        if(loginUser == null){
            WebUtils.renderUnAnth(response,403,"用户未登录");
            throw new RuntimeException("用户未登录");
        }
        log.info("======redis authenticated user:{}======",loginUser.getUsername());

        if (claims != null) {
            // 手动组装一个认证对象
            Authentication authentication = new UsernamePasswordAuthenticationToken(loginUser,null, loginUser.getAuthorities());
            // 将认证对象放到上下文中
            log.info("======security authenticated user:{}======",loginUser.getUsername());
            log.info("======security authenticated permissions:{}======",loginUser.getPermissions());
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        filterChain.doFilter(request,response);
    }

}
